Chapter 4 Spatial data in R
The previous chapter provided a short recap of the R basics that will help you progress through this book. This chapter will focus on the fundamentals of mapping, i.e. the different types of data that can be used to make a map.
This chapter is written for those with some knowledge of R and little experience with spatial data. If you are familiar with the different data types (points, lines, polygons and vectors), you may move on to the next chapter where visualisation of data types is explained in more detail. However you never know, you may learn something here too.
Learning objectives
[andy: still thinking how best to structure these]
- Be able to describe and use points, lines, polygons and raster data types
- Understand the difference between vector and raster data
- Be able to read in data of the 4 types into R from files and other sources
- Know that the current best packages for manipulating spatial data are package
sffor vector and packagerasterfor raster. - Be comfortable visualising the four different spatial data types in R using packages
mapview&raster
Maps are used for a wide range of purposes. In this book we focus on using maps to present data.
A map can provide a model of reality to help the reader see where things or events are located. This could be on the scale of a street, a neighbourhood, a country or a continent. Depending on the topics you’re interested in, this could be focussed on disease cases, landcover dynamics, location of schools. The opportunities are endless.
The data that we can represent on a map can be divided into four main types :
- points
- lines
- polygons
- rasters
Points can be used to represent the locations of e.g. cities, buildings, disease cases, sample sites or wildlife records. They can be used to represent the centre of an area. Points can be chosen when the shape of the location is not important. Thus for a map representing a continent, cities can be represented by points because the area of cities would not be visible.
Lines may represent physical features such as rivers or roads, or routes travelled, or abstract links between point locations.
[andy to continue …]
All spatial data types require a coordinate reference system (CRS) identification to place data in the correct location on the earth. We will discuss this in more detail later. For now, just be aware that a code may need to be entered to ensure that data display in the correct place. Note also that spatial data types can be stored in many different formats, from Shapefile (.shp + .dbf + .prj + …), to GeoPackage (.gpkg), to CSV files (.csv). This can be overwhelming at times. Don’t worry we will come to these later [Andy great if we can specify exactly where this information can be found].
List of episodes
4.1 Points
Let’s take an imaginary walk outside. What do you see? Houses, cars, trees… All these objects have unique coordinates that can be used to identify their exact location. On a map, the objects can be drawn as points with their latitude and longitude coordinate indicating their exact location in relation to other objects and places. Depending on the scale of your map, points can represent anything from a house, health clinic, city or district. You, as the map creator, can decide the scale of your own map.
4.1.1 Example
Lets try and visualise the capital cities of Africa which we have stored in the afrilearndata package.
Just a quick reminder of the necessary packages
library(afrilearndata) #load afrilearndata package
#In case the data isn't loaded into your R environment automatically, it can be loaded individually using the code below.
data(africapitals) #location of the African capitalsWe will start by downloading the necessary packages: sf package. This package is necessary to read in the spatial data files. tmap package. This package is necessary to create the maps.
#install.packages("sf") #install sf package
#install.packages("tmap") #install tmap package
library(sf) #load sf package
library(tmap) #load tmap packageNote More information can be found about the different packages using the Help tools.
Now, let’s look at the data file that contains information about the African capitals. A quick summary of the spatial aspects (geometry) of the datafile can be checked using the following code:
print(st_geometry(africapitals)) #printing information on the geometry## Geometry set for 50 features
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -17.48 ymin: -29.31 xmax: 47.51 ymax: 36.84
## Geodetic CRS: WGS 84
## First 5 geometries:
We can see from the results that the African capital data file contains 50 points (capitals) with geometry type POINT.
Let’s print the first 6 rows of data, so we can see how the coordinates of each African captial is stored in the database.
head(africapitals) #First 6 rows of data are printed## Simple feature collection with 6 features and 4 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -0.2 ymin: -18.89 xmax: 47.51 ymax: 36.77
## Geodetic CRS: WGS 84
## capitalname countryname pop iso3c geometry
## 280 Abuja Nigeria 178462 NGA POINT (7.17 9.18)
## 308 Accra Ghana 2029143 GHA POINT (-0.2 5.56)
## 382 Addis Abeba Ethiopia 2823167 ETH POINT (38.74 9.03)
## 996 Algiers Algeria 2029936 DZA POINT (3.04 36.77)
## 1584 Antananarivo Madagascar 1463754 MDG POINT (47.51 -18.89)
## 2193 Asmara Eritrea 578860 ERI POINT (38.94 15.33)
The capitals all have one latitude and one longitude value. The geometry of the point data is stored as POINT (Latitude, Longitude). On the location where the latitude and longitude overlap, a point will be drawn when POINT data is visualised. There is also another column that contains the population of the capital.
Let’s now visualise the African capitals by plotting their geometry using the tmap package.
tm_shape(africapitals) + #specify the data file
tm_dots() # displaying the point geometryThe tmap package works similar to the ggplot package. You need to first specify the data file you want to visualise using tm_shape(), after which the exact format of the spatial data can be specified (points, lines, polygons). As we are working with point data in this example, the tm_dots() function is used. As with ggplot, there is a lot of flexibility in the colouring, shapes and sizes of the dots. For example, the dots can be turned red and labelled with the name of the city.
tm_shape(africapitals) +
tm_dots("red")+ # displaying the point geometry as red dots
tm_text("capitalname", size=0.7 ) #adding the nameAs you can see in the example above, the labelling makes the image messy. In these instances it is important to think about the message you are trying to convey with your map. If the labelling is essential, you can look up the help section of the ‘tm_text’ using the help tool and play around with the different options to clean up the map further.
4.1.2 Exercises
Exercise 1 In this first exercise, we will use the same African capital data as our example. Below, We have visualised all capitals with > 1.400.000 people using green squares of size 1. However, the code isn’t working. Can you find the four mistakes?
Hint: if you get stuck, look at ‘?tm_dots’
#africapitals_filtered=africapitals %>%
# dplyr::filter((africapitals$iso3c) > 1.400.000)
#tm_shape(africapitals_filtered) +
# tm_dots("green", size=0.5)Answer:
* In the initial filter, africapitals$iso3c needs to be changed to africapitals$pop
* Dots in 1.400.000 need to be removed
* The shape of the dots need to be specified as squares using shape=22
* The size of the points needs to be 1.
africapitals_filtered=africapitals %>%
dplyr::filter((africapitals$pop) > 1400000)
tm_shape(africapitals_filtered) +
tm_dots("green", shape = 22, size=1)4.1.2.1 Exercise 2
We will now use capital and African airport data.
Visualise the capitals and airports in one map, with capitals as grey large filled-in circles and airports as smaller blue not-filled triangles.
Hint: if you get stuck, look at ‘Add Points to a Plot’ in the help section.
Hint: When both points and lines are mapped, datasets need to be identified seperately in tm_shape() before the use of tm_dots().
Answer:
tm_shape(africapitals) +
tm_dots(col="grey", shape = 19, size=3) +
tm_shape(afriairports) +
tm_dots(col="blue", shape = 2, size=1)4.2 Lines
In previous episode we looked at point data, such as capitals and airports. We are often interested in how these different locations on a map are connect to eachother. These connections are visualised using lines. Roads, rivers and flight pathes are just a few of the many ways that lines are used. Lines are one dimensional data which are drawn using points (and thus point data) connected to eachother in a set order. Depending on the detail of the lines, more or less point data are connected.
4.2.1 Example
For this example, we will look at the trans-African highway network. Let’s start by looking at a quick summary of the spatial aspects (geometry).
print(st_geometry(afrihighway)) #printing information on the geometry## Geometry set for 100 features
## Geometry type: LINESTRING
## Dimension: XYZ
## Bounding box: xmin: -17.38929 ymin: -33.95247 xmax: 43.13781 ymax: 37.08586
## z_range: zmin: 0 zmax: 0
## Geodetic CRS: WGS 84
## First 5 geometries:
The results show that the African highway network contains 100 lines with geometry type LINESTRING.
Let’s now print the first 6 rows of data to see how line data are stored.
head(afrihighway) #First 6 rows of data are printed## Simple feature collection with 6 features and 1 field
## Geometry type: LINESTRING
## Dimension: XYZ
## Bounding box: xmin: -17.36938 ymin: 14.76957 xmax: -6.800537 ymax: 33.98436
## z_range: zmin: 0 zmax: 0
## Geodetic CRS: WGS 84
## # A tibble: 6 x 2
## Name geometry
## <chr> <LINESTRING [°]>
## 1 Western Sahara (Morocco) Link Z (-16.94778 21.34438 0, -16.85303 21.96343 0, -16.54541 22.12636 0, -16.32568 22.7457...
## 2 Mauritania Border- Dakar Link Z (-17.36938 14.76957 0, -16.9519 14.77488 0, -16.73218 14.97663 0, -16.22681 15.58071...
## 3 Nouakchott- Senegal Border Link Z (-15.81069 16.52036 0, -16.11694 16.72039 0, -16.10596 17.22476 0, -15.99609 17.6649...
## 4 Western Sahara Border- Nouakchott Link Z (-15.99128 18.08646 0, -16.01807 18.49003 0, -16.17188 18.84391 0, -16.16089 19.0932...
## 5 Marrakesh- Western Sahara (Morocco) Link Z (-12.95837 27.67623 0, -12.7002 28.0041 0, -12.12891 28.06229 0, -11.45874 28.31405 ...
## 6 Rabat- Marrakesh Link Z (-8.12439 31.79238 0, -8.02002 31.8589 0, -7.915649 32.50976 0, -7.767334 32.67175 0...
Line data contain a string of data points with latitude and longitude: LINESTRING(Latitude1, Longitude1, Latitude2, Longitude2, Latitude3, Longitude3,.. ). During mapping, these points are connected to form a line.
Let’s visualise these linestrings in red by plotting their geometry using the tmap package.
tm_shape(afrihighway) +
tm_lines("red") Similar to point data, the lines can be illustrated in a large variety of ways. Please check the tm_lines() help section to familiarise yourself with the many layout options available.
Now we add the capitals from previous episode in blue.
tm_shape(africapitals) +
tm_dots("blue", size=0.5)+
tm_shape(afrihighway) +
tm_lines("red") It is great to see how the capitals are connected by the trans-African highway network.
Note The order of tm_dots() and tm_lines() matters. If you want the points overlaying the lines, it should be placed after the lines coding and visa versa.
4.2.1.1 Exercise 3
In the below exercise we have tried to visualise all the capitals and only the roads starting with the letter ‘b.’ However, we have messed up the order of the code. Can you rearrange the code?
# tm_shape(africapitals) +
# tm_shape(afrihighway_ex1)+
# tm_dots("blue", size=0.5)+
# tm_lines("blue")
#afrihighway_ex1=afrihighway[grep("^B", afrihighway$Name),]Answer:
afrihighway_ex1=afrihighway[grep("^B", afrihighway$Name),]
tm_shape(africapitals) + #important that capitals are visualised first
tm_dots("blue", size=0.5)+
tm_shape(afrihighway_ex1)+
tm_lines("blue")4.2.1.2 Exercise 4
Visualise the trans-African highway network, with line width associated with the length of the road. The function st_length is used to calculate the length of a line.
Answer:
#[julie-anne this seems to error]
# Error: Assigned data `value` must be compatible with existing data.
# x Existing data has 100 rows.
# x Assigned data has 99 rows.
# afrihighway$length=tapply(st_length(afrihighway), afrihighway$Name, sum)
# tm_shape(afrihighway) +
# tm_lines(lwd = `length`)4.3 Polygons
Polygons are lines with the same first and last coordinate. When the polygon line is connected, the same start and end point results in a closed shape. Similar to lines, depending on the detail of the map, more or less points can be used to create a polygon. This two-dimensional data is most often used to visualise country and continent boundaries.
The continent outline of Africa is a multipolygon.
plot(st_geometry(africontinent), col = "lightblue")
One polygon is used to visualise the mainland of Africa. An additional polygon is used for Madagascar. Together they represent the whole African continent.
Sometimes several polygons are necessary to capture a more complex shape. The different polygons in one data row indicate either areas to include or exclude from the final image. These are called multipolygons. An example of a multipolygon is the country border of South Africa. Lesotho is entirely surrounded by South Africa. If we want to visualise South Africa, we need to make sure that the Lesotho area is excluded. Visualisation of South Africa therefore requires two polygons, one to outline the outer borders and one to highlight the area to exclude (Lesotho country borders). Below, the South African border is visualised.
africountries_ex=africountries %>%
filter(`name` == "South Africa")
plot(st_geometry(africountries_ex), col = "lightblue")
As you can see in the image, when the polygon of South Africa is visualised, a white area is visible inside the country (representing Lesotho), which is not part of South Africa.
4.3.1 Example
For this example, we will look at the country borders of African countries. Let’s visualise the geometry of the datafile first.
print(st_geometry(africountries)) #printing information on the geometry## Geometry set for 51 features
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -17.62504 ymin: -34.81917 xmax: 51.13387 ymax: 37.34999
## Geodetic CRS: WGS 84
## First 5 geometries:
The country border file contains 51 country outlines with geometry type MULTIPOLYGON.
If we print the first 6 rows of data, we can see how each country border is stored in the database.
head(africountries) #First 6 rows of data are printed## Simple feature collection with 6 features and 11 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -17.06342 ymin: -13.25723 xmax: 51.13387 ymax: 27.65643
## Geodetic CRS: WGS 84
## name name_long pop_est gdp_md_est lastcensus income_grp iso_a3
## 1 Tanzania Tanzania 53950935 150600.0 2002 5. Low income TZA
## 2 W. Sahara Western Sahara 603253 906.5 NA 5. Low income ESH
## 11 Dem. Rep. Congo Democratic Republic of the Congo 83301151 66010.0 1984 5. Low income COD
## 12 Somalia Somalia 7531386 4719.0 1987 5. Low income SOM
## 13 Kenya Kenya 47615739 152700.0 2009 5. Low income KEN
## 14 Sudan Sudan 37345935 176300.0 2008 4. Lower middle income SDN
## geometry name_fr name_pt name_af
## 1 MULTIPOLYGON (((33.90371 -0... Tanzanie Tanzânia Tanzanië
## 2 MULTIPOLYGON (((-8.66559 27... Sahara occidental Saara Ocidental Wes-Sahara
## 11 MULTIPOLYGON (((29.34 -4.49... Congo-Kinshasa Congo - Kinshasa Demokratiese Republiek van die Kongo
## 12 MULTIPOLYGON (((41.58513 -1... Somalie Somália Somalië
## 13 MULTIPOLYGON (((39.20222 -4... Kenya Quênia Kenia
## 14 MULTIPOLYGON (((24.56737 8.... Soudan Sudão Soedan
## name_sw
## 1 Tanzania
## 2 Sahara Magharibi
## 11 Jamhuri ya Kidemokrasia ya Kongo
## 12 Somalia
## 13 Kenya
## 14 Sudan
Here, the geometry data contain a list with (multiple) polygons, with each polygon represented as a list of data points with latitude and longitude. These points are connected to form polygons, which are either used to include or exclude areas from the final image. The geometry of the multipolygon data is stored as MULTIPOLYGON (((Latitude1, Longitude1, Latitude2, Longitude2, Latitude3, Longitude3,.. ),(Latitude1, Longitude1, ..)),(Latitude1, Longitude1, …))).
Lets visualise these multipolygons with black lines.
tm_shape(africountries) +
tm_borders() #if only borders need to be visualisedtm_shape(africountries) +
tm_polygons() #if you want the image to specify the multipolygon areaNow we can add the capitals and highways from previous episodes
tm_shape(africountries) +
tm_borders()+
tm_shape(africapitals) +
tm_dots("blue", size=0.5)+
tm_shape(afrihighway) +
tm_lines("red") 4.3.1.1 Exercise 5
Multiple choice to identify if datafiles contain point, line or (multi)polygon geometry.
1 Look up the bus routes in your home area. Which data type would you use to visualise this data? a Point data b Line data c Multipolygon data d All of the above
answer: b
2 What kind of data type is necessary to visualise the countries part of the the Economic Community of West African States (ECWAS) community? a Point data b Line data c Multipolygon data d All of the above
answer: c
3 Which data type is necessary for the authors to visualise the below image. (need help visualising this with the right approval from authors) https://www.google.com/url?sa=i&url=https%3A%2F%2Fcdiac.ess-dive.lbl.gov%2Fepubs%2Fndp%2Fndp055%2Fndp055.html&psig=AOvVaw2qJ0HAjtU9ytbSWT-qFR0R&ust=1616679119758000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKD8l5qFye8CFQAAAAAdAAAAABBW a Point data b Line data c Multipolygon data d All of the above
answer: d
4.3.1.2 Exercise 6
Visualise the African borders of all countries with an area larger than 300.000 km^2. The function st_area is used to calculate the area within a polygon.
Hint: make sure you check the units
Answer:
africountries$area_sqm <- st_area(africountries)
africountries$area_sqkm <-africountries$area_sqm / 1000000
africountries_filtered = africountries %>%
dplyr::filter(as.numeric(africountries$area_sqkm) > 300000)
tm_shape(africountries_filtered) +
tm_borders()4.4 Rasters
Points, lines and polygons, in their essence, consist of points with a longitude and latitude value. The data files of these vectors look very similar. Raster data are a group on their own. Raster data consist of a matrix of grid cells (pixels), with each grid cell representing a geographical location with a value illustrating a characteristic of that location. Raster data are mainly used when displaying data that are continuous accross space. For example, population density, landcover variation and elevation data extracted from satellites, drones and surveys.
The more grid cells a raster file contains, the smoother the visualisation of the characteristic will be. However, a large number of grids also means a large heavy file, which may be difficult to run. Whenever you are working with raster files, think about your goal and objective. The highest resolution might not always be necessary.
To read in raster data, we first need to install and load the ‘raster’ package.
#install.packages("raster") #install raster package
library(raster) # load raster packageWe can now start visualising raster data.
4.4.1 Example
For this example we use African population data from 2000 and 2020. Let’s look at the information within the file first.
print(afripop2000) #printing information on the raster data file## class : RasterLayer
## dimensions : 434, 413, 179242 (nrow, ncol, ncell)
## resolution : 0.1666667, 0.1666667 (x, y)
## extent : -17.62625, 51.20708, -34.97542, 37.35792 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## source : memory
## names : ppp_2000_1km_Aggregated
## values : 0, 16606.66 (min, max)
The population raster data from 2000 contains 434 rows, 413 columns and a total of 179.242 grid cells with geometry type RasterLayer .
Let’s print the first 10 rows of data.
head(afripop2000) #First 6 rows of data are printed## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 8 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 9 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## 10 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Why do you think all rows are empty?
Let’s take a look at more grid cells.
getValues(afripop2000)## [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [11] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [21] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [31] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [41] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [51] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [61] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [71] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [81] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [101] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [111] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [121] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [131] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [141] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [151] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [161] NaN 31.530225 28.976320 27.053571 136.428734 294.236007 267.969128 NaN NaN NaN
## [171] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [181] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [191] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [201] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [211] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [221] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [231] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [241] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [251] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [261] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [271] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [281] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [291] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [301] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [311] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [321] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [331] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [341] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [351] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [361] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [371] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [381] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [391] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [401] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [411] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [421] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [431] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [441] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [451] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [461] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [471] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [481] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [491] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [501] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [511] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [521] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [531] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [541] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [551] NaN NaN NaN NaN NaN NaN 26.581936 57.259988 98.798142 NaN
## [561] NaN 10.485693 36.448088 56.846905 NaN NaN NaN NaN NaN NaN
## [571] NaN NaN 40.543849 46.735299 58.994084 38.973892 112.350208 219.639630 95.674532 84.673351
## [581] NaN NaN NaN NaN 130.251743 NaN NaN NaN NaN NaN
## [591] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [601] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [611] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [621] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [631] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [641] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [651] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [661] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [671] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [681] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [691] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [701] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [711] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [721] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [731] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [741] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [751] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [761] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [771] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [781] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [791] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [801] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [811] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [821] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [831] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [841] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [851] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [861] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [871] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [881] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [891] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [901] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [911] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [921] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [931] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [941] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
## [951] NaN NaN NaN NaN NaN NaN 149.317101 78.438325 78.944654 20.285452
## [961] 22.651681 2.156746 NaN NaN NaN NaN NaN NaN 53.467887 60.544859
## [971] 100.295662 229.078813 38.838185 1500.185943 98.050085 44.672719 38.032209 57.407279 3322.625715 6.796631
## [981] 17.307500 24.163841 147.894095 47.972929 109.734964 58.400623 78.840521 50.609101 52.652782 44.439908
## [991] 52.390443 75.373201 523.321409 NaN NaN 22.653634 50.320826 76.936087 94.302234 NaN
## [ reached getOption("max.print") -- omitted 178242 entries ]
The printed matrix shows that the raster layer consists of a matrix with values. The grid cells can be empty if no data is available. This just results in no visualisation (NA or empty) at those locations.
Lets visualise the population data with the country borders. Note that population density data are highly skewed. To ensure both high and low density areas are clearly visible, we have to specify the data breaks manually.
tm_shape(afripop2020) +
tm_raster(breaks=c(0,2,20,200,2000,25000))We can make the image easier to interpret by using a palette from the viridisLite package, moving the legend using tm_layout() and including the African borders.
tm_shape(afripop2020) +
tm_raster(palette = rev(viridisLite::magma(5)), breaks=c(0,2,20,200,2000,25000)) + #specify the breaks of the palette
tm_layout(legend.position = c("left","bottom"))+ #moves the legend to the left bottom corner
tm_shape(africountries) +
tm_borders() Now we can add the capitals and highways from previous episodes.
tm_shape(afripop2000) +
tm_raster(palette = rev(viridisLite::magma(5)), breaks=c(0,2,20,200,2000,25000)) +
tm_layout(legend.position = c("left","bottom"))+
tm_shape(africountries) +
tm_borders() 4.4.1.1 Exercise 7
Visualise the population data of 2000 using a different palette from the viridisLite package. Increase the number of breaks to six. Which breaks are most appropriate?
tm_shape(afripop2020) +
tm_raster(palette = rev(viridisLite::plasma(6)), breaks=c(0,2,20,200,2000,20000, 25000)) +
tm_layout(legend.position = c("left","bottom"))+
tm_shape(africountries) +
tm_borders()4.5 Further resources
If you are interested in learning more about the different spatial data types, please visit:
4.6 Summary/key points
The image below gives a short recap of the different data types discussed in this chapter. You should now be able to recognize, load and manipulate these data types using the sf and raster and visualise them using the tmap package.
